package main

import (
	"fmt"
	"time"
)

//协作感知合约（CSC）
type CSC struct {
	Id             string    `json:"id"`
	SACId          string    `json:"SACId"`
	Deadline       time.Time `json:"deadline"`       //结束时间Tddl
	Deposit        float64   `json:"deposit"`        //定金ds
	MaxNum         int       `json:"maxNum"`         //支持的最大传感器数量N1
	MiniTtustValue float64   `json:"miniTtustValue"` //参与的最小信任值TVthr
	SensorNum      int       `json:"sensorNum"`      //传感器数量
	SensorList     []Sensor  `json:"sensorList"`     //参与的传感器
	MsgList        []string  `json:"msgList"`        //探测结果集合
	Result         string    `json:"result"`         //探测结果
}

//传感器
type Sensor struct {
	Address    string  `json:"address"`    //地址
	TrustValue float64 `json:"trustValue"` //信任值  0-1
	Deposit    float64 `json:"deposit"`    //存款
	MsgId      string  `json:"msgId"`
	LocationX  float64 `json:"locationX"` //坐标x
	LocationY  float64 `json:"locationY"` //坐标y
	Timestamp  int64   `json:"timestamp"` //时间戳
	SR         string  `json:"SR"`
	Msg        string  `json:"msg"`  //探测结果
	RSIG       string  `json:"RSIG"` //环签名
}

//合作感知合约初始化
func CSCInit(miniTtustValue float64, deposit float64, maxNum int) CSC {
	c := CSC{
		MiniTtustValue: miniTtustValue,
		Deposit:        deposit,
		MaxNum:         maxNum,
		SensorNum:      0,
		SensorList:     make([]Sensor, 0),
	}
	return c
}

//传感器注册 Addr,dpt,TV of the node
func (csc *CSC) SensorRegister(senor Sensor) bool {
	if csc.CheckRegisterQuality(senor) {
		//传感器检测通过
		csc.SensorList = append(csc.SensorList, senor)
		csc.SensorNum++
		fmt.Printf("csc.SensorList: %v\n", csc.SensorList)
		fmt.Printf("csc.SensorNum: %v\n", csc.SensorNum)
		//检测是否需要更换传感器
		if csc.SensorNum > csc.MaxNum {
			//删除trustvalue最低的传感器
			index := csc.GetLowestTVIndex()
			csc.SensorList = append(csc.SensorList[:index], csc.SensorList[index+1:]...)
			csc.SensorNum--
		}
	}
	return false
}

//检查传感器是否有资格 TVi,addri
func (csc CSC) CheckRegisterQuality(senor Sensor) bool {
	if senor.Deposit > csc.Deposit {
		diffDeposit := senor.Deposit - csc.Deposit
		//把余额差值转化成trustValue
		diffTV := diffDeposit / senor.Deposit
		if (senor.TrustValue + diffTV) > csc.MiniTtustValue {
			//如果有空位置或者传感器的信任值更高，则有资格
			if csc.SensorNum < csc.MaxNum || senor.TrustValue > csc.GetLowestTV() {
				return true
			}
		}
	}
	return false
}

//上传感知结果
func (csc *CSC) UplodaSensingData(senor Sensor) bool {
	//TODO环签名验证
	for _, s := range csc.SensorList {
		if s.Address == senor.Address {
			csc.MsgList = append(csc.MsgList, senor.Msg)
			return true
		}
	}
	return false
}

//融合传感器的所有感测结果
func (csc *CSC) Fusion() bool {
	//TODO融合传感器的所有感测结果
	return true
}

//获得最小的trustValue
func (csc CSC) GetLowestTV() float64 {
	lowestTV := 0.0
	if len(csc.SensorList) > 0 {
		lowestTV = csc.SensorList[0].TrustValue
		for _, s := range csc.SensorList {
			if lowestTV > s.TrustValue {
				lowestTV = s.TrustValue
			}
		}
	}
	return lowestTV
}

//获得最小的trustValue的index
func (csc CSC) GetLowestTVIndex() int {
	lowestTV := 0.0
	index := -1
	if len(csc.SensorList) > 0 {
		lowestTV = csc.SensorList[0].TrustValue
		index = 0
		for i, s := range csc.SensorList {
			if lowestTV > s.TrustValue {
				lowestTV = s.TrustValue
				index = i
			}
		}
	}
	return index
}
